<template>
  <div class="menu-container">
    <el-button type="primary" @click="openFolder">
      加载文件夹<el-icon class="el-icon--right"><Search /></el-icon>
    </el-button>
    <div class="date-filter-label">日期筛选器：</div>
    <div style="width: 300px">
      <el-date-picker
        v-model="value2"
        type="daterange"
        unlink-panels
        range-separator="To"
        start-placeholder="开始日期"
        end-placeholder="结束日期"
        :shortcuts="shortcuts"
        :size="size"
        style="width: 300px !important"
      />
    </div>
    
    <el-button 
      type="danger" 
      :icon="Delete" 
      circle 
      @click="confirmClearAll"
      style="margin-left: auto"
      title="清除所有数据和标记"
    />
  </div>
</template>

<script setup>
import { ref, watch } from 'vue'
import { ElMessageBox } from 'element-plus'
import { Delete } from '@element-plus/icons-vue'

import EXIFParser from 'exif-parser'
import { openDB } from 'idb'

const emit = defineEmits(['imagesLoaded', 'clearAllData'])

/**
 * 打开文件夹并处理其中的图片文件
 * 1. 通过Electron API选择文件夹
 * 2. 读取文件夹中的图片文件
 * 3. 解析每张图片的EXIF数据
 * 4. 生成缩略图并计算文件哈希
 * 5. 存储图片元数据到IndexedDB
 * 6. 触发imagesLoaded事件
 */
const openFolder = async () => {
  if (window.electronAPI) {
    const result = await window.electronAPI.showOpenDialog({
      properties: ['openDirectory']
    })
    if (!result.canceled) {
      const folderPath = result.filePaths[0]
      console.log('Selected folder:', folderPath)
      
      try {
        console.log('kk')
        const getAllFiles = async (dir) => {
          const entries = await window.electronAPI.readDir(dir)
          let allFiles = []
          
          for (const entry of entries) {
            const fullPath = `${dir}/${entry}`
            const isDirectory = !/\.\w+$/.test(entry)
            
            if (isDirectory) {
              const subFiles = await getAllFiles(fullPath)
              allFiles = allFiles.concat(subFiles)
            } else if (/\.(jpg|jpeg|png|gif|bmp|webp)$/i.test(entry)) {
              allFiles.push(fullPath)
            }
          }
          return allFiles
        }
        
        const imageFiles = await getAllFiles(folderPath)
        
        if (imageFiles.length === 0) {
          console.warn('警告: 所选文件夹中没有找到图片文件')
          return
        }
        
        const processedImages = []
        
        for (const file of imageFiles) {
          const fileName = file.split('/').pop()
          const fileData = await window.electronAPI.readFile(file, 'binary')
          const buffer = ensureArrayBuffer(fileData)
          
          if (!buffer || buffer.byteLength === 0) {
            console.error(`错误: 无法读取文件 ${filePath} 或文件为空`)
            continue
          }
          
          let exifData = { tags: {} }
          try {
            const parser = EXIFParser.create(buffer)
            exifData = parser.parse()
          } catch (exifError) {
            console.warn(`无法解析文件 ${file} 的EXIF数据:`, exifError)
          }
          
          const thumbnailUrl = await generateThumbnail(buffer)
          const fileHash = await calculateFileHash(buffer)
          console.log(exifData)
          await storeImageMetadata({
            filePath: file,
            fileName: fileName,
            exifData: exifData.tags,
            thumbnailUrl,
            fileHash
          })
          
          processedImages.push({
            filePath: file,
            fileName: fileName,
            exifData: exifData.tags,
            thumbnailUrl,
            fileHash,
            buffer
          })
        }
        emit('imagesLoaded', processedImages)
      } catch (error) {
        console.error('处理图片时出错:', error)
      }
    }
  } else {
    console.error('Electron API not available')
  }
}

// 保留的工具函数
/**
 * 确保文件数据转换为ArrayBuffer格式
 * @param {ArrayBuffer|Uint8Array} fileData - 原始文件数据
 * @returns {ArrayBuffer} 转换后的ArrayBuffer
 */
function ensureArrayBuffer(fileData) {
  let buffer
  if (fileData instanceof ArrayBuffer) {
    buffer = fileData
  } else {
    buffer = new Uint8Array(fileData).buffer
  }
  return buffer
}

/**
 * 生成图片缩略图
 * @param {ArrayBuffer} buffer - 图片二进制数据
 * @returns {Promise<string>} 缩略图的DataURL
 */
async function generateThumbnail(buffer) {
  return new Promise((resolve) => {
    const img = new Image()
    img.onload = () => {
      const canvas = document.createElement('canvas')
      const ctx = canvas.getContext('2d')
      const maxSize = 200
      let width = img.width
      let height = img.height
      
      if (width > height) {
        if (width > maxSize) {
          height *= maxSize / width
          width = maxSize
        }
      } else {
        if (height > maxSize) {
          width *= maxSize / height
          height = maxSize
        }
      }
      
      canvas.width = width
      canvas.height = height
      ctx.drawImage(img, 0, 0, width, height)
      resolve(canvas.toDataURL('image/jpeg', 0.7))
    }
    img.onerror = () => resolve(null)
    img.src = URL.createObjectURL(new Blob([buffer], {type: 'image/jpeg'}))
  })
}

/**
 * 计算文件SHA-256哈希值
 * @param {ArrayBuffer} buffer - 文件二进制数据
 * @returns {Promise<string>} 文件的哈希字符串
 */
async function calculateFileHash(buffer) {
  const hashBuffer = await crypto.subtle.digest('SHA-256', buffer)
  const hashArray = Array.from(new Uint8Array(hashBuffer))
  return hashArray.map(b => b.toString(16).padStart(2, '0')).join('')
}

/**
 * 存储图片元数据到IndexedDB
 * @param {Object} metadata - 图片元数据对象
 */
async function storeImageMetadata(metadata) {
  try {
    const db = await openDB('imageMetadataDB', 1, {
      upgrade(db) {
        if (!db.objectStoreNames.contains('images')) {
          db.createObjectStore('images', { keyPath: 'fileHash' })
        }
      }
    })
    await db.put('images', metadata)
  } catch (error) {
    console.error('存储图片元数据时出错:', error)
    throw error
  }
}
const size = ref<'default' | 'large' | 'small'>('default')

const value1 = ref('')
const value2 = ref('')

watch(value2, (newVal) => {
  if (newVal && newVal[0] && newVal[1]) {
    emit('dateRangeChanged', [newVal[0], newVal[1]])
  }
})

// 清空所有数据
const confirmClearAll = () => {
  ElMessageBox.confirm(
    '此操作将清除所有地图标记和数据库内容，且无法恢复，确认继续吗？',
    '警告',
    {
      confirmButtonText: '确认',
      cancelButtonText: '取消',
      type: 'warning',
    }
  ).then(async () => {
    try {
      // 清除IndexedDB数据
      const db = await openDB('imageMetadataDB', 1)
      await db.clear('images')
      
      // 触发事件通知父组件清除地图标记
      emit('clearAllMarkers')
      
      console.log('所有数据和标记已清除')
    } catch (error) {
      console.error('清除数据时出错:', error)
    }
  }).catch(() => {
    // 用户取消操作
  })
}

const shortcuts = [
  {
    text: '近一周',
    value: () => {
      const end = new Date()
      const start = new Date()
      start.setTime(start.getTime() - 3600 * 1000 * 24 * 7)
      return [start, end]
    },
  },
  {
    text: '近一月',
    value: () => {
      const end = new Date()
      const start = new Date()
      start.setTime(start.getTime() - 3600 * 1000 * 24 * 30)
      return [start, end]
    },
  },
  {
    text: '近三月',
    value: () => {
      const end = new Date()
      const start = new Date()
      start.setTime(start.getTime() - 3600 * 1000 * 24 * 90)
      return [start, end]
    },
  },
  {
    text: '近半年',
    value: () => {
      const end = new Date()
      const start = new Date()
      start.setTime(start.getTime() - 3600 * 1000 * 24 * 180)
      return [start, end]
    },
  },
  {
    text: '近一年',
    value: () => {
      const end = new Date()
      const start = new Date()
      start.setTime(start.getTime() - 3600 * 1000 * 24 * 365)
      return [start, end]
    },
  },
  {
    text: '近三年',
    value: () => {
      const end = new Date()
      const start = new Date()
      start.setTime(start.getTime() - 3600 * 1000 * 24 * 365 *3)
      return [start, end]
    },
  },
  {
    text: '近十年',
    value: () => {
      const end = new Date()
      const start = new Date()
      start.setTime(start.getTime() - 3600 * 1000 * 24 * 365 *10)
      return [start, end]
    },
  },
]
</script>

<style scoped>
.menu-container {
  display: flex;
  justify-content: center;
  align-items: center;
  gap: 20px;
  padding: 10px;
  background: #f5f5f5;
  border-top: 1px solid #ddd;
  min-width: fit-content;
}

.open-folder-btn {
  padding: 8px 16px;
  background-color: #42b983;
  color: white;
  border: none;
  border-radius: 4px;
  cursor: pointer;
}

.open-folder-btn:hover {
  background-color: #3aa876;
}
</style>